package name.weily.liba.widgets

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

open class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    var isSelected = false
    private val maps by lazy { mutableMapOf<Int, View>() }

    fun <T : View> getView(vid: Int): T? {
        val v = maps[vid]
        return if (v == null) {
            val v1 = itemView.findViewById<T>(vid)
            maps[vid] = v1
            v1
        } else {
            maps[vid] as? T
        }
    }

}

open class RecyclerViewAdapter<T>
constructor(protected open val createView: ((parent: ViewGroup, viewType: Int) -> View),
            protected open val bindVH: ((holder: ViewHolder, item: T?, position: Int)-> Unit))
    : RecyclerView.Adapter<ViewHolder>() {

    constructor() : this(createView = { parent, viewType ->
        LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false)
    }, bindVH = { vh, item, pos ->
        vh.getView<TextView>(android.R.id.text1)?.text = item.toString()
    })

    protected open val mutableList by lazy { mutableListOf<T>() }
    open var itemClickListener: ((View, T?, Int) -> Unit)? = null
    open var itemLongClickListener: ((View, T?, Int) -> Boolean)? = null

    open fun setDataList(list: List<T>) {
        mutableList.clear()
        mutableList.addAll(list)
        notifyDataSetChanged()
    }

    open fun appendDataList(list: List<T>) {
        mutableList.addAll(list)
        notifyDataSetChanged()
    }

    open fun getDataList() = mutableList

    open fun getItemData(position: Int) : T? {
        return if (position in 0 until itemCount) mutableList[position] else null
    }

    open fun removeAt(position: Int) {
        if (position in 0 until itemCount) {
            mutableList.removeAt(position)
            notifyItemRemoved(position)
        }
    }

   open fun insertAt(position: Int, item: T) {
        if (position in 0 until itemCount) {
            mutableList.add(position, item)
            notifyItemInserted(position)
        }
    }

    open fun replaceAt(position: Int, item: T) {
        if (position in 0 until itemCount) {
            mutableList[position] = item
            notifyItemChanged(position)
        }
    }

    open fun clearData() {
        mutableList.clear()
        notifyDataSetChanged()
    }

    protected open fun onClick(v: View) {
        itemClickListener?.let {
            val tag = v.tag
            if (tag is Int) {
                it.invoke(v, getItemData(tag), tag)
            }
        }
    }

    protected open fun onLongClick(v: View) : Boolean {
        itemLongClickListener?.let {
            val tag = v.tag
            if (tag is Int) {
                return it.invoke(v, getItemData(tag), tag)
            }
        }
        return false
    }

    override fun getItemCount() = mutableList.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val vh = ViewHolder(createView(parent, viewType))
        vh.itemView.setOnClickListener(this::onClick)
        vh.itemView.setOnLongClickListener(this::onLongClick)
        return vh
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        bindVH(holder, getItemData(position), position)
        holder.itemView.tag = position
    }
}





